from flask import render_template, g, session, abort, current_app, request, jsonify
from info.modules.news import news_blu
from info.models import User, News, Comment,CommentLike
from info.utils.common import user_login
from info import constants, db
from info.utils.response_code import RET



@news_blu.route("/followed_user",methods=["POST"])
@user_login
def followed_user():
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR,errmsg="用户未登录")

    user_id = request.json.get("user_id")
    action = request.json.get("action")

    if not all([user_id,action]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数错误")

    if action not in("follow","unfollow"):
        return jsonify(errno=RET.PARAMERR,errmsg="参数错误")

    try:
        author = User.query.get(user_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据库查询错误")

    if not author:
        return jsonify(errno=RET.DATAERR,errmsg="未查询到数据")

    if action == "follow":

        if user not in author.followers:
            author.followers.append(user)
        else:
            return jsonify(errno=RET.DATAEXIST,errmsg="当前用户已被关注")

    else:
        if user in author.followers:
            author.followers.remove(user)
        else:
            return jsonify(errno=RET.DATAEXIST,errmsg="当前用户未被关注")

    return jsonify(errno=RET.OK,errmsg="操作成功")





@news_blu.route("/comment_like", methods=["POST"])
@user_login
def set_comment_like():
    """
    点赞和取消点赞的逻辑
    1、接收参数 comment_id action
    2、校验参数
    3、CommentLike()往点赞的表中添加或者删除一条数据
    4、返回响应
    :return:
    """
    user = g.user

    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    comment_id = request.json.get("comment_id")
    action = request.json.get("action")

    if not all([comment_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")

    if action not in ["add", "remove"]:
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        comment_id = int(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    try:
        comment_obj = Comment.query.get(comment_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")

    if not comment_obj:
        return jsonify(errno=RET.NODATA, errmsg="该评论不存在")

    comment_like_obj = CommentLike.query.filter_by(comment_id=comment_id, user_id=user.id).first()
    # 业务逻辑
    if action == "add":
        if not comment_like_obj:
            # 如果我是添加一条点赞，要初始化一个点赞对象，并将数据添加进去，add，commit
            comment_like = CommentLike()
            comment_like.comment_id = comment_id
            comment_like.user_id = user.id
            db.session.add(comment_like)
            comment_obj.like_count += 1
    else:
        # 如果这条点赞存在，我才能删除点赞
        if comment_like_obj:
            db.session.delete(comment_like_obj)
            comment_obj.like_count -= 1
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库保存失败")

    return jsonify(errno=RET.OK, errmsg="OK")




@news_blu.route("/news_comment",methods=["POST"])
@user_login
def news_comment():

    user = g.user

    if not user:
        return jsonify(errno=RET.SESSIONERR,errmsg="用户未登陆")

    news_id = request.json.get("news_id")
    comment_str = request.json.get("comment")
    parent_id = request.json.get("parent_id")

    if not all([news_id,comment_str]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数错误")

    try:
        news_id = int(news_id)
        if parent_id:
            parent_id = int(parent_id)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg="参数类型错误")

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据库查询错误")

    if not news:
        return jsonify(errno=RET.NODATA,errmsg="该条新闻不存在")

    comment = Comment()
    comment.news_id = news_id
    comment.user_id = user.id
    comment.content = comment_str

    if parent_id:
        comment.parent_id = parent_id

    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据库保存失败")
    comment_count = Comment.query.filter(Comment.news_id == news_id).count()

    return jsonify(errno=RET.OK,errmsg="OK",data=comment.to_dict(),comment_count=comment_count)






@news_blu.route("/news_collect",methods=["POST"])
@user_login
def news_collect():
    user = g.user

    if not user:
        return jsonify(errno=RET.SESSIONERR,errmsg="用户未登录")

    news_id = request.json.get("news_id")
    action = request.json.get("action")

    if not all([news_id,action]):
        return jsonify(errno=RET.PARAMERR,errmsg="参数错误")

    if action not in ["collect","cancel_collect"]:
        return jsonify(errno=RET.PARAMERR,errmsg="参数错误")

    try:
        news_id = int(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg="参数格式不对")

    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg="数据库查询错误")

    if not news:
        return jsonify(errno=RET.NODATA,errmsg="该条新闻不存在")

    if action == "collect":
        if news not in user.collection_news:
            user.collection_news.append(news)

    else:

        if news in user.collection_news:
            user.collection_news.remove(news)

    return jsonify(errno=RET.OK,errmsg="OK")


@news_blu.route("/<int:news_id>")
@user_login
def detail(news_id):
    user = g.user
    # 1、查询点击排行新闻
    clicks_news = []
    try:
        clicks_news = News.query.order_by(News.clicks.desc()).limit(
            constants.CLICK_RANK_MAX_NEWS).all()  # [obj, obj, obj]
    except Exception as e:
        current_app.logger.error(e)

    # [obj, obj, obj] --> [{}, {}, {}, {}]
    clicks_news_li = [news.to_basic_dict() for news in clicks_news]

    # 2、显示新闻的具体信息
    # 判断新闻id存不存在
    # if not news_id:
    #     abort(404)
    # # 判断新闻id是不是整数类型
    # try:
    #     news_id = int(news_id)
    # except Exception as e:
    #     current_app.logger.error(e)
    #     abort(404)


    # # 判断新闻id存不存在
    # if not news_id:
    #     abort(404)
    # # 判断新闻id是不是整数类型
    # try:
    #     news_id = int(news_id)
    # except Exception as e:
    #     current_app.logger.error(e)
    #     abort(404)
    # 判断新闻是不是存在
    news = None
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)

    if not news:
        abort(404)

        news.clicks += 1
        # 详情页收藏和已收藏是由is_collected
    is_collected = False
    # 在什么样的一个情况下  is_collected = True
    # 需求：如果 该用户收藏了该条新闻 is_collected = True
    # 1、保证用户存在
    # 2、新闻肯定存在
    # 3、该条新闻在用户收藏新闻的列表中
    # 4、用户收藏新闻的列表----> user.collection_news.all()  [news, news]
    if user and news in user.collection_news.all():
        is_collected = True

    is_followed = False

    # 用户关注作者
    author = news.user
    if user and author:
        # 课件中的代码有bug
        # 1、如果user在author的粉丝中
        # 2、如果author在user的关注者中  if author in user.followed:

        if user in author.followers:
            is_followed = True

    comments = []
    try:
        comments = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)

    # comments_dict_li = [comment.to_dict() for comment in comments]

    # 点赞第一种方法
    # comment_like_ids = []
    # if user:
    #     comment_ids = [comment.id for comment in comments]
    #     comment_likes = CommentLike.query.filter(CommentLike.user_id == user.id,
    #                                              CommentLike.comment_id.in_(comment_ids)).all()
    #     comment_like_ids = [comment_like.comment_id for comment_like in comment_likes]



    # comments_dict_li = [comment.to_dict() for comment in comments]
    comments_dict_li = []
    for comment in comments:
        comment_dict = comment.to_dict()
        comment_dict["is_like"] = False
        # 如果comment_dict["is_like"] = True代表已经点赞
        # 如果该条评论的id在我的点赞评论id列表中
        # if comment.id in comment_like_ids:
        if user and CommentLike.query.filter(CommentLike.comment_id == comment.id,
                                             CommentLike.user_id == user.id).first():
            comment_dict["is_like"] = True
        comments_dict_li.append(comment_dict)



    data = {
            "user_info":user.to_dict() if user else None,
            "clicks_news_li":clicks_news_li,
            "news":news.to_dict(),
            "is_collected":is_collected,
            "comments_dict_li":comments_dict_li,
            "is_followed":is_followed
        }
    return render_template("news/detail.html",data=data)